use std::sync::{
  atomic::{AtomicUsize, Ordering},
  Arc,
};

use tokio::runtime::{Builder, Runtime};

use crate::global_defin::global::format_current_dt_by_default;

static mut RUNTIME: Option<Arc<Runtime>> = None;
static THREAD_ID: AtomicUsize = AtomicUsize::new(0);


/**
 * 获取全局线程池的Arc副本。
 * 
 * 这个函数通过lazy_static实现线程池的单例模式。如果线程池还未初始化，
 * 则使用指定的配置进行初始化，并返回其Arc引用。
 * 
 * 返回值:
 *  - Arc<Runtime>: 线程池的原子引用计数副本，可安全地在多个线程间共享。
 */
pub fn get_rt() -> Arc<Runtime> {
  unsafe {
    RUNTIME
      .get_or_insert_with(|| {
        // 获取系统CPU核心数，用于确定线程池的大小。
        let thread_num = num_cpus::get() + 1;

        // 打印初始化日志，包括CPU核心数。
        println!("初始化线程池 ~~..CPU数量:{}", thread_num);
        
        // 创建一个线程池，配置包括：线程数量、线程名称、线程栈大小、启用的所有特性，
        // 以及线程启动和停止时的回调函数。
        Arc::new(
          Builder::new_multi_thread()
            .worker_threads(thread_num + 1) // 线程池的工作线程数为CPU核心数加一。
            .thread_name_fn(|| { // 设置线程名称，线程ID递增。
              let id = THREAD_ID.fetch_add(1, Ordering::SeqCst);
              format!("w_{}", id)
            })
            .thread_stack_size(10 * 1024 * 1024) // 设置每个线程的栈大小为10MB。
            .enable_all() // 启用Tokio运行时的所有功能。
            .on_thread_start(|| { // 线程启动时打印日志。
              println!(
                "{}:线程`{}`启动。。。",
                format_current_dt_by_default(),
                std::thread::current().name().expect("get_rt()获取线程名称失败")
              )
            })
            .on_thread_stop(|| { // 线程停止时打印日志。
              println!(
                "{}:线程`{}`停止。。",
                format_current_dt_by_default(),
                std::thread::current().name().expect("get_rt()获取线程名称失败")
              )
            })
            .build()
            .expect("get_rt()创建线程池失败"),
        )
      })
      .clone() // 返回线程池Arc的一个新副本。
  }
}